package com.zrx.app.android.UTIL;

import android.location.Location;
import android.os.AsyncTask;
import android.os.Looper;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zrx.app.android.R;
import com.zrx.app.android.ZRXApplication;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/*
* 远程连接
* */
public class RemoteConn {
    public static final String TAG = "RemoteConn";     //每一个Activity都有一个对应的标志
    private static RemoteConn instance = null;
    String prefix = null;
    Map<String, String> loginInfo = null;
    String email, password;
    private JSONObject userInfo;
    private boolean isOnline;
    private boolean test;

    public boolean isMainThread() {
        return Looper.getMainLooper() == Looper.myLooper();
    }

    public RemoteConn(String email, String password) {
        this.test = ZRXApplication.getAppContext().getResources().getBoolean(R.bool.isTest);
        if (test) {
            prefix = ZRXApplication.getAppContext().getResources().getString(R.string.version_test_conn);
        } else {
            prefix = ZRXApplication.getAppContext().getResources().getString(R.string.version_prod_conn);
        }


        this.email = email;
        this.password = password;
    }

    private RemoteConn() {
        prefix = ZRXApplication.getAppContext().getResources().getString(R.string.version_test_conn);
    }

    public static RemoteConn createInstance(String email, String password) {                                //创建一个用户实例
        instance = new RemoteConn(email, password);
        return instance;
    }

    public static RemoteConn createPrivateInstance(String email, String password) {
        RemoteConn ins = new RemoteConn(email, password);
        ins.login();
        return ins;
    }

    public static RemoteConn getInstance() {
        if (instance == null)
            instance = new RemoteConn();
        return instance;
    }

    public String getEmail() {
        return email;
    }

    public String getPassword() {
        return password;
    }

    public boolean isAuthedAndTryLogin(){
        if(!isAuthed()) {
            login();
            return isAuthed();
        }else
            return true;
    }

    public boolean isAuthed() {
        AsyncTask<RemoteConn, Void, JSONObject> at = new AsyncTask<RemoteConn, Void, JSONObject>() {
            @Override
            protected JSONObject doInBackground(RemoteConn... params) {
                try {
                    JSONObject resp = getJSONResult(params[0].getHttpConn(prefix + "/auth/getUserInfo").getInputStream());
                    return resp;
                } catch (Exception e) {
                    Log.w(TAG, e.getMessage());
                }
                return null;
            }

        };
        AsyncTask<RemoteConn, Void, JSONObject> re = at.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, this);

        try {
            //JSONObject resp = getJSONResult(this.getHttpConn(prefix+"/auth/getUserInfo").getInputStream());
            JSONObject resp = re.get(10, TimeUnit.SECONDS);
            if (resp != null && resp.getInteger("code") == 0 && resp.get("data") != null) {
                this.userInfo = resp.getJSONObject("data");
                return true;
            }
        } catch (Exception e) {
            //Log.w(TAG, e.getMessage());
        }




        return false;
    }

    public JSONObject getUserInfo() {
        return userInfo;
    }

    public boolean isOnline() {
        return isOnline;
    }

    public JSONObject fetchData(String mainURL,String key,int size, int page) {
        HttpURLConnection httpConn = null;
        try {
            String url = prefix + mainURL +"/" + size + "/" + page;
            if (key != null && !"".equals(key))
                url += "/" + URLEncoder.encode(key, "UTF-8");
//            String encodedURL = URLEncoder.encode(url, "UTF-8");
//            httpConn = getHttpConn(encodedURL);
            httpConn = getHttpConn(url);

            JSONObject re = getJSONResult(httpConn.getInputStream());
            return re.getJSONObject("data");
        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
        }

        return null;
    }


    public JSONObject fetchData2(String mainURL,String key,int size, int page) {
        HttpURLConnection httpConn = null;
        try {
            String url = prefix + mainURL +"/" + size + "/" + page;
            if (key != null && !"".equals(key))
                url += "/" + URLEncoder.encode(key, "UTF-8");
//            String encodedURL = URLEncoder.encode(url, "UTF-8");
//            httpConn = getHttpConn(encodedURL);
            httpConn = getHttpConn(url);

            JSONObject re = getJSONResult(httpConn.getInputStream());
            return re.getJSONObject("data");
        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
        }

        return null;
    }

    public JSONObject fetchData_reason(String mainURL){
        HttpURLConnection httpConn = null;
        try {
            httpConn = getHttpConn(mainURL);
            JSONObject re = getJSONResult(httpConn.getInputStream());
            return re.getJSONObject("data");
        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
        }

        return null;
    }

           public boolean getFile(String fileId, String outPath) {
            HttpURLConnection httpConn = null;
            try {
                httpConn = getHttpConn(prefix + "/tango/getFile/" + fileId);
                FileOutputStream fos = new FileOutputStream(outPath);
                BufferedInputStream bis = new BufferedInputStream(httpConn.getInputStream());
                int count = 0;
                byte[] buff = new byte[4096];
                while ((count = bis.read(buff, 0, 4096)) != -1) {
                    fos.write(buff, 0, count);
                }
                fos.close();
                bis.close();

            return true;
        } catch (IOException e) {
            Log.d(TAG, e.getMessage());
        }

        return false;
    }

    private HttpURLConnection getHttpConn(String url) throws IOException {
        if (loginInfo == null)
            login();

        HttpURLConnection httpConn = (HttpURLConnection) new URL(url).openConnection();
        httpConn.setRequestMethod("POST");
        httpConn.setDoOutput(true);
        httpConn.setDoInput(true);
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Accept", "application/json");

        httpConn.setReadTimeout(30 * 1000); // 缓存的最长时间
        httpConn.setUseCaches(false); // 不允许使用缓存
        httpConn.setRequestProperty("connection", "keep-alive");
        httpConn.setRequestProperty("Charsert", "UTF-8");


        Set<Map.Entry<String, String>> entrySet = loginInfo.entrySet();
        for (Map.Entry<String, String> ele : entrySet) {
            httpConn.setRequestProperty(ele.getKey(), ele.getValue());
        }

        return httpConn;

    }

    static public String getResult(InputStream is) {

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return sb.toString();

//        Scanner sc = new Scanner(is);
//        StringBuilder sb = new StringBuilder();
//        while (sc.hasNextLine()) {
//            sb.append(sc.nextLine());
//            sb.append("\n");
//        }
//        return sb.toString();
    }

    JSONObject getJSONResult(InputStream is) {
        JSONObject re = null;
        try {
            re = JSON.parseObject(getResult(is));
        } catch (Exception e) {
            // TODO: handle exception
        }
        return re;
    }

    public JSONObject login(){
        if(isMainThread()){
            try {
                AsyncTask at=new AsyncTask() {
                    @Override
                    protected Object doInBackground(Object[] params) {
                        return loginTask();
                    }
                };
                return (JSONObject) at.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).get(5,TimeUnit.SECONDS);
            }catch (Exception e){
                return null;
            }
        }else
            return loginTask();
    }


    public JSONObject loginTask() {

        try {
            Map<String, String> loginInfo = new HashMap<>();

            URL url = new URL(prefix + "/auth/csrf");
            URLConnection conn = url.openConnection();
            HttpURLConnection httpConn = (HttpURLConnection) conn;
            JSONObject pp = getJSONResult(httpConn.getInputStream());
            String tokenName = pp.getString("headerName");
            String token = pp.getString("token");
            Map<String, List<String>> header = conn.getHeaderFields();
            List<String> cookies = header.get("Set-Cookie");
            String sessionid = "";
            for (String cookie : cookies) {
                if (cookie.contains("SESSION"))
                    sessionid = cookie.split(";")[0].substring(8);
            }
            loginInfo.put(tokenName, token);
            loginInfo.put("Cookie", "SESSION=" + sessionid);

            HttpURLConnection httpConn2 = (HttpURLConnection) new URL(prefix + "/auth/ajaxLogin").openConnection();
            httpConn2.setRequestMethod("POST");
            httpConn2.setDoOutput(true);
            httpConn2.setDoInput(true);
            httpConn2.setRequestProperty("Content-Type", "application/json");
            httpConn2.setRequestProperty("Accept", "application/json");
            httpConn2.setRequestProperty(tokenName, token);
            httpConn2.setRequestProperty("Cookie", "SESSION=" + sessionid);
            JSONObject json = new JSONObject();
            json.put("email", email);
            json.put("password", password);
            json.put("src", "pad");
            json.put("ver", ZRXApplication.getAppContext().getResources().getString(R.string.version));

            String imei= ZRXUTIL.getIMEI();
            if(imei!=null)
                json.put("imei",imei);
            Location location=ZRXUTIL.getLocation();
            if(location!=null)
                json.put("location",location);


            httpConn2.getOutputStream().write(json.toJSONString().getBytes("utf-8"));

            JSONObject re2 = getJSONResult(httpConn2.getInputStream());

            Log.i(TAG, re2.toJSONString());

            this.loginInfo = loginInfo;
            this.userInfo = getJSONResult(this.getHttpConn(prefix + "/auth/getUserInfo").getInputStream());
            Log.i(TAG, userInfo.toJSONString());
            isOnline = true;
            return re2;
        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
        }

        return null;
    }

    public HttpURLConnection uploadFiles(String actionUrl,
                                         Map<String, String> params, JSONArray files) throws IOException {

        String BOUNDARY = java.util.UUID.randomUUID().toString();
        String PREFIX = "--", LINEND = "\r\n";
        String MULTIPART_FROM_DATA = "multipart/form-data";
        String CHARSET = "UTF-8";

        URL uri = new URL(actionUrl);
        HttpURLConnection conn = getHttpConn(actionUrl);
        conn.setReadTimeout(30 * 1000); // 缓存的最长时间
        conn.setUseCaches(false); // 不允许使用缓存
        conn.setRequestProperty("connection", "keep-alive");
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Charsert", "UTF-8");
        conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);

        StringBuilder sb = new StringBuilder();

        if (params != null) {
            // 首先组拼文本类型的参数
            for (Map.Entry<String, String> entry : params.entrySet()) {
                sb.append(PREFIX);
                sb.append(BOUNDARY);
                sb.append(LINEND);
                sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
                sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
                sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
                sb.append(LINEND);
                sb.append(entry.getValue());
                sb.append(LINEND);
            }

        }

        DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
        if (null != sb.toString()) {
            outStream.write(sb.toString().getBytes());
        }

        // 发送文件数据
        if (files != null)
            for (int i = 0; i < files.size(); ++i) {
                JSONObject ele = files.getJSONObject(i);
                String name = ele.getString("name");
                String filename = ele.getString("filename");
                String contentType = ele.getString("contentType");
                InputStream inputStream = (InputStream) ele.get("inputStream");

                StringBuilder sb1 = new StringBuilder();
                sb1.append(PREFIX);
                sb1.append(BOUNDARY);
                sb1.append(LINEND);
                sb1.append("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\""
                        + LINEND);
                sb1.append("Content-Type: " + contentType + "; charset=" + CHARSET + LINEND);
                sb1.append(LINEND);
                outStream.write(sb1.toString().getBytes());

                InputStream is = inputStream;
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = is.read(buffer)) != -1) {
                    outStream.write(buffer, 0, len);
                }

                is.close();
                outStream.write(LINEND.getBytes());
            }

        // 请求结束标志
        byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
        outStream.write(end_data);
        outStream.flush();

        return conn;

    }

    public JSONObject uploadFiles(String id, String key, String path,String type) {
        try {
            JSONArray files = new JSONArray();
            JSONObject ele = new JSONObject();
            ele.put("name", key);
            if("照片".equals(type)||"jpg".equals(type)){
                ele.put("filename", key + ".jpg");
                ele.put("contentType", "image/jpeg");
            }else if("视频".equals(type)||"mp4".equals(type)){
                ele.put("filename", key + ".mp4");
                ele.put("contentType", "video/mpeg4");
            }

            ele.put("inputStream", new FileInputStream(path));
            files.add(ele);
            HttpURLConnection conn = uploadFiles(prefix + "/tango/uploadFiles/" + id, null, files);//getHttpConn();
            JSONObject re = getJSONResult(conn.getInputStream());

            Log.d(TAG, re.toJSONString());
            return re;
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return null;
    }

    public JSONObject uploadFilesByUrl(String url, String key, String path, String type) {
        try {
            JSONArray files = new JSONArray();
            JSONObject ele = new JSONObject();
            ele.put("name", key);
            if("照片".equals(type)||"jpg".equals(type)){
                ele.put("filename", key + ".jpg");
                ele.put("contentType", "image/jpeg");
            }else if("视频".equals(type)||"mp4".equals(type)){
                ele.put("filename", key + ".mp4");
                ele.put("contentType", "video/mpeg4");
            }

            ele.put("inputStream", new FileInputStream(path));
            files.add(ele);
            HttpURLConnection conn = uploadFiles(prefix + url, null, files);//getHttpConn();
            JSONObject re = getJSONResult(conn.getInputStream());

            Log.d(TAG, re.toJSONString());
            return re;
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return null;
    }

    public JSONObject uploadText(String id, JSONObject uploadText) {
        try {
            HttpURLConnection conn = getHttpConn(prefix + "/tango/uploadAddtionalData/" + id);

            conn.getOutputStream().write(uploadText.toJSONString().getBytes());
            JSONObject re = getJSONResult(conn.getInputStream());
            Log.d(TAG, re.toJSONString());
            return re;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public JSONObject submit(String id) {
        try {
            HttpURLConnection conn = getHttpConn(prefix + "/tango/toStateExaming/" + id);
            JSONObject re = getJSONResult(conn.getInputStream());
            Log.d(TAG, re.toJSONString());
            return re;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public JSONObject submitByUrl(String url) {
        try {
            HttpURLConnection conn = getHttpConn(prefix + url);
            JSONObject re = getJSONResult(conn.getInputStream());
            Log.d(TAG, re.toJSONString());
            return re;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public boolean isTest() {
        return test;
    }

    //征信查询方法
    public JSONObject queryCredit(String name, String idCardNum,String phoNum, String creditCardNum,String creditType,String idCard1, String idCard2, String authSignature, String authPhoto, String auth3rdPartPhoto) {
        try {
            final JSONArray files = new JSONArray();
            String []arr={idCard1,idCard2,authSignature,authPhoto,auth3rdPartPhoto};
            String []names={"idCard1","idCard2","authSignature","authPhoto","auth3rdPartPhoto"};//图片资源名称集合
            for(int i=0;i<arr.length;++i){
                File e=new File(arr[i]);
                JSONObject ele=new JSONObject();
                if(e.exists()&&e.isFile()){
                    ele.put("name",names[i]);
                    ele.put("filename",e.getName());
                    ele.put("contentType","image/jpeg");
                    try {
                        ele.put("inputStream", new FileInputStream(e));
                        files.add(ele);
                    }catch (Exception e1){
                    }
                }
            }

            final HashMap<String,String> textParams=new HashMap<>();
            textParams.put("name",name);
            textParams.put("idCardNum",idCardNum);
            textParams.put("mobile",phoNum);
            textParams.put("bankCard",creditCardNum);
            textParams.put("creditType",creditType);


            AsyncTask at=new AsyncTask() {
                @Override
                protected Object doInBackground(Object[] params) {
                    JSONObject re = null;
                    try {
                        HttpURLConnection conn = uploadFiles(prefix + "/tango/credit/queryFromAndroidWithBankCardAndMobile/", textParams, files);//getHttpConn();
                        re = getJSONResult(conn.getInputStream());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return re;
                }


            };
            at.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, this);
            return (JSONObject) at.get(20,TimeUnit.SECONDS);
        } catch (Exception e) {
            Log.w(TAG, e.getMessage());
        }
        return null;
    }

    public JSONObject listCredit() {
        try{
            AsyncTask at=new AsyncTask() {
                @Override
                protected Object doInBackground(Object[] params) {
                    JSONObject re = null;
                    try {
                        HttpURLConnection conn = getHttpConn(prefix + "/tango/credit/listFromAndroidNew/50/0");
                        re = getJSONResult(conn.getInputStream());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return re;
                }


            };
            at.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, this);
            return (JSONObject) at.get(10,TimeUnit.SECONDS);
        }catch (Exception e){

        }
        return null;
    }

    public JSONObject listReason(final String idReason) {
        try{
            AsyncTask at=new AsyncTask() {
                @Override
                protected Object doInBackground(Object[] params) {
                    JSONObject re = null;
                    try {
                        HttpURLConnection conn = getHttpConn(prefix + "/tango/listAllCommentsById/" + idReason);
                        re = getJSONResult(conn.getInputStream());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return re;
                }
            };
            at.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, this);
            return (JSONObject) at.get(10,TimeUnit.SECONDS);
        }catch (Exception e){
        }
        return null;
    }

}
